﻿using System;
using System.Data.SqlClient;
using System.IO;
using System.Web.UI.WebControls;
using design.WorkWithDataClasses;

namespace design
{
	public class PageTemplate : System.Web.UI.Page
	{
		protected int currentPage;
		protected int pagesCount;
		protected const int itemsOnPage = 3;
		protected int itemsCount;
		protected string site = "Default.aspx";
		protected int randomItem;

		protected virtual void Page_Load(object sender, EventArgs e)
		{
			string connectionStr = System.Configuration.ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;
			SqlConnection connection = new SqlConnection(connectionStr);
			connection.Open();

			itemsCount = this.GetItemsCount(connection);
			pagesCount = itemsCount / itemsOnPage + 1;
			currentPage = this.GetVarFromUrl("page");
			if (currentPage == -1)
			{
				currentPage = 1;
			}

			int lowerBorder = 1 + itemsOnPage * (currentPage - 1);
			int upperBorder = itemsOnPage + itemsOnPage * (currentPage - 1);

			this.FillHeadContent(connection);

			int currentItem = this.GetVarFromUrl("currentItem");
			if (currentItem == -1)
			{
				this.FillMainContent(connection, lowerBorder, upperBorder);
			}
			else
			{
				this.FillMainContent(connection, currentItem, currentItem);
			}

			connection.Close();
		}

		protected int GetVarFromUrl(string var)
		{
			string str = Request.RawUrl;
			if (str.Contains(var))
			{
				str = str.Substring(str.IndexOf(var) + var.Length + 1);
			}
			if (str.Contains("&"))
			{
				str = str.Remove(str.IndexOf("&"));
			}
			int tmp;
			if (Int32.TryParse(str, out tmp) && tmp > 0)
			{
				return tmp;
			}
			return -1;
		}

		/// <summary>
		/// считаем количество страниц для paging
		/// </summary>
		protected virtual int GetItemsCount(SqlConnection connection)
		{
			string cmdText = "select count(*) as c from books";
			SqlCommand cmd = new SqlCommand(cmdText, connection);
			SqlDataReader reader = cmd.ExecuteReader();
			reader.Read();

			int count = Convert.ToInt32(reader["c"]);
			reader.Close();

			return count;
		}

		/// <summary>
		/// заполняем HeadContent
		/// </summary>
		protected void FillHeadContent(SqlConnection connection)
		{
			Random rand = new Random();
			randomItem = rand.Next(1, itemsCount);
			string cmdText = this.GetSQLStr(randomItem, randomItem);
			SqlCommand cmd = new SqlCommand(cmdText, connection);
			SqlDataReader reader = cmd.ExecuteReader();
			reader.Read();

			ContentPlaceHolder headContent = (ContentPlaceHolder)Page.Master.FindControl("FeaturedContent");
			headContent.Controls.Clear();
			this.AddControls(headContent, 0, reader, true); // индекс у headitem пусть будет 0

			reader.Close();
		}

		/// <summary>
		/// заполняем MainContent
		/// </summary>
		protected void FillMainContent(SqlConnection connection, int lowerBorder, int upperBorder)
		{
			ContentPlaceHolder bodyContent = (ContentPlaceHolder)Page.Master.FindControl("MainContent");
			bodyContent.Controls.Clear();

			string cmdText = this.GetSQLStr(lowerBorder, upperBorder);
			SqlCommand cmd = new SqlCommand(cmdText, connection);
			SqlDataReader reader = cmd.ExecuteReader();

			int i = 0;
			while (reader.Read())
			{
				i++;
				this.AddControls(bodyContent, i, reader, false);
			}

			bodyContent.Controls.Add(this.CreateOtherPagesRef());

			reader.Close();
		}

		/// <summary>
		/// создаем ссылки на другие страницы
		/// </summary>
		protected Literal CreateOtherPagesRef()
		{
			Literal references = new Literal();
			references.ID = "references";
			references.Text = "<p style='text-align: center;'>";

			if (currentPage > 1)
			{
				references.Text += "<a href='" + site + "?page=" + (currentPage - 1) + "'>[Назад]</a>";
			}
			else
			{
				references.Text += "<span style='color:grey;'>[Назад]</span>";
			}

			if (pagesCount > 7) // если много страниц
			{
				if (currentPage > 3 && currentPage < pagesCount - 2)
				{
					references.Text += "<a href='" + site + "?page=" + 1 + "'>[1]</a>";
					references.Text += " ... ";
					for (int i = currentPage - 2; i <= currentPage + 2; i++)
					{
						if (currentPage != i)
						{
							references.Text += "<a href='" + site + "?page=" + i + "'>[" + i + "]</a>";
						}
						else
						{
							references.Text += "<span style='color:grey;'>[" + i + "]</span>";
						}
					}
					references.Text += " ... ";
					references.Text += "<a href='" + site + "?page=" + pagesCount + "'>[" + pagesCount + "]</a>";
				}
				else if (currentPage <= 3)
				{
					for (int i = 1; i <= 5; i++)
					{
						if (currentPage != i)
						{
							references.Text += "<a href='" + site + "?page=" + i + "'>[" + i + "]</a>";
						}
						else
						{
							references.Text += "<span style='color:grey;'>[" + i + "]</span>";
						}
					}
					references.Text += " ... ";
					references.Text += "<a href='" + site + "?page=" + pagesCount + "'>[" + pagesCount + "]</a>";
				}
				else
				{
					references.Text += "<a href='" + site + "?page=" + 1 + "'>[" + 1 + "]</a>";
					references.Text += " ... ";
					for (int i = pagesCount - 4; i <= pagesCount; i++)
					{
						if (currentPage != i)
						{
							references.Text += "<a href='" + site + "?page=" + i + "'>[" + i + "]</a>";
						}
						else
						{
							references.Text += "<span style='color:grey;'>[" + i + "]</span>";
						}
					}
				}
			}
			else
			{
				for (int i = 1; i <= pagesCount; i++)
				{
					if (currentPage != i)
					{
						references.Text += "<a href='" + site + "?page=" + i + "'>[" + i + "]</a>";
					}
					else
					{
						references.Text += "<span style='color:grey;'>[" + i + "]</span>";
					}
				}
			}

			if (currentPage < pagesCount)
			{
				references.Text += "<a href='" + site + "?page=" + (currentPage + 1) + "'>[Далее]</a>";
			}
			else
			{
				references.Text += "<span style='color:grey;'>[Далее]</span>";
			}
			references.Text += "</p>";

			return references;
		}

		protected virtual void AddControls(ContentPlaceHolder content, int i, SqlDataReader reader, bool head)
		{
			Book book = new Book(Convert.ToInt32(reader["id"]), Convert.ToInt32(reader["id_author"]),
				Convert.ToInt32(reader["id_media"]), reader["description"].ToString(),
				reader["path"].ToString(), reader["date"].ToString(), reader["title"].ToString());

			string href;
			if (head)
			{
				href = site + "?currentItem=" + randomItem;
			}
			else
			{
				href = site + "?currentItem=" + (itemsOnPage * (currentPage - 1) + i);
			}

			Literal contentLiteral = new Literal();
			contentLiteral.ID = "contentLiteral_ID_" + i;
			contentLiteral.Text = "<br/><a href='" + href + "' ><span class='itemTitle'>" + book.Title + "</span></a>";
			contentLiteral.Text += "<div class='Container'>";
			contentLiteral.Text += "<a href='" + href + "' ><img class='mainImg' src='" + reader["mpath"] + "' alt='mainImg' /></a>";
			contentLiteral.Text += "<div class='info'>";
			contentLiteral.Text += "<p> <br/> <span style='text-decoration: underline;'>Информация о книге:</span><br/>";
			contentLiteral.Text += "<b>Название:</b>" + book.Title + "<br/>";
			contentLiteral.Text += "<b>Автор:</b>" + reader["alast"] + "<br/>";
			contentLiteral.Text += "<b>Дата выхода:</b>" + book.Date + "<br/>";
			contentLiteral.Text += "<b>Описание:</b><br/>" + book.Description + " </p>";
// описание слишком короткое (255 символов)
			//contentLiteral.Text += "<p><a href='" + book.Path + "'>Скачать</a> </p>";

			contentLiteral.Text += "</div></div><br/>";
			content.Controls.Add(contentLiteral);
			content.Controls.Add(this.CreateButton(i, book.Path));

			if (!head)
			{
				Literal endItemLiteral = new Literal();
				endItemLiteral.ID = "endItemLiteral_ID_" + i;
				endItemLiteral.Text += "<div style='background-image: url(../images/dotted-lines.png); background-repeat: repeat-x; height: 6px;'></div><br/>";
				content.Controls.Add(endItemLiteral);
			}
		}

// кнопка - фигня. нужна ссылка, но как сделать ссылкой?
		protected Button CreateButton(int index, string bookPath)
		{
			Button b = new Button();
			b.Text = "Скачать";
			b.ApplyStyleSheetSkin(this);
			b.ID = "button_" + bookPath + "_" + index;
// !!! говнокод. как в кнопку запихнуть данные?
			b.Click += OnDownloadButtonClick;
			return b;
// как убрать ссылку с кнопки? в header-е не скачивает, а просто переходит на default.aspx
		}

		protected void OnDownloadButtonClick(object sender, EventArgs e)
		{
			Button b = sender as Button;
			string str = b.ID;
			str = str.Substring(str.IndexOf("button_") + 7);
			str = str.Substring(0, str.LastIndexOf('_'));
			if (File.Exists(Server.MapPath(str)))
			{
				Response.Clear();
				Response.AddHeader("content-disposition", "attachment;filename=" + str);
				Response.WriteFile(Server.MapPath(str));
				Response.End();
// записывает файл без разширения
			}
		}

		protected virtual string GetSQLStr(int lowerBorder, int upperBorder)
		{
			string cmdText = "select * ";
			cmdText += "from ( ";
			cmdText += "select row_number() over( ";
			cmdText += "order by date desc) as rownum, ";
			cmdText += "books.id, books.id_author, books.id_media, books.description, ";
			cmdText += "books.path, books.date, books.title, ";
			cmdText += "medias.path as mpath, ";
			cmdText += "authors.lastname as alast ";
			cmdText += "from books, medias, authors ";
			cmdText += "where books.id_media = medias.id and books.id_author = authors.id ) ";
			cmdText += "as b ";
			cmdText += "where rownum between " + lowerBorder + " and " + upperBorder;

			return cmdText;
		}
	}
}

// при просмотре 1й страницы - что делать со списком страниц [][][][]
